//////////////////////////////////////////////////////////////////////////
#include "HotSpot.h"
#include "Application/Application.h"
//////////////////////////////////////////////////////////////////////////
HotSpot::HotSpot()
: m_mouseEventFunctor(NULL)
, m_mouseEnterFunctor(NULL)
, m_mouseLeaveFunctor(NULL)
, m_mouseInside(false)
{

}
//////////////////////////////////////////////////////////////////////////
HotSpot::~HotSpot()
{
	if(m_mouseEnterFunctor)
	{
		delete m_mouseEnterFunctor;
		m_mouseEnterFunctor = NULL;
	}
	if(m_mouseEventFunctor)
	{
		delete m_mouseEventFunctor;
		m_mouseEventFunctor = NULL;
	}
	if(m_mouseLeaveFunctor)
	{
		delete m_mouseLeaveFunctor;
		m_mouseLeaveFunctor = NULL;
	}
}
//////////////////////////////////////////////////////////////////////////
void HotSpot::addPoint( const hlp::Pointf& point )
{
	m_points.push_back(point);
	m_transformedPoints.push_back(hlp::Pointf(0.0f, 0.0f));
	m_transformedPoints[m_transformedPoints.size()-1] = hlp::transformPoint(point, m_transformationMatrix);
}
//////////////////////////////////////////////////////////////////////////
void HotSpot::addPoint( float x, float y )
{
	addPoint(hlp::Pointf(x, y));
}
//////////////////////////////////////////////////////////////////////////
void HotSpot::clearPoints()
{
	m_points.clear();
}
//////////////////////////////////////////////////////////////////////////
void HotSpot::update( float dt )
{
	CompositeObject::update(dt);
	
	checkMouseIn();

	if(Application::instance()->updateHSListNeeded())
	{
		Application::instance()->addHotSpot(this);
	}
}
//////////////////////////////////////////////////////////////////////////
void HotSpot::transformatePoints()
{
	for(int i = 0; i < static_cast<int>(m_points.size()); ++i)
	{
		m_transformedPoints[i] = hlp::transformPoint(m_points[i], m_transformationMatrix);
	}
}
//////////////////////////////////////////////////////////////////////////
void HotSpot::updateTransformationMatrix()
{
	CompositeObject::updateTransformationMatrix();
	transformatePoints();
}
//////////////////////////////////////////////////////////////////////////
bool HotSpot::testPoint( const hlp::Pointf& point )
{
	if(m_points.size() < 3)
		return false;
	
	bool ratio = hlp::pointSegmentRatio(point, m_transformedPoints[0], m_transformedPoints[1]);
	for(size_t i = 1; i < m_points.size()-1; ++i)
	{
		if(hlp::pointSegmentRatio(point, m_transformedPoints[i], m_transformedPoints[i+1]) != ratio)
			return false;
	}

	return (hlp::pointSegmentRatio(point, m_transformedPoints[m_transformedPoints.size()-1], m_transformedPoints[0]) == ratio);
}
//////////////////////////////////////////////////////////////////////////
bool HotSpot::checkMouseEvent(int buttonNumber, bool isDown)
{
	if(!m_mouseInside)
		return false;
	
	if(m_mouseEventFunctor)
		return (*m_mouseEventFunctor)(isDown);

	return false;
}
//////////////////////////////////////////////////////////////////////////
void HotSpot::setParent( CompositeObject* parent )
{
	CompositeObject::setParent(parent);
	Application::instance()->setUpdateHSListNeeded();
}
//////////////////////////////////////////////////////////////////////////
bool HotSpot::checkMouseIn()
{
	bool pointIn = testPoint(Application::instance()->getMousePos());
	if(pointIn == m_mouseInside)
		return false;
	
	m_mouseInside = pointIn;

	if(pointIn)
	{
		if(m_mouseEnterFunctor)
			return (*m_mouseEnterFunctor)();
	}
	else
	{
		if(m_mouseLeaveFunctor)
			return (*m_mouseLeaveFunctor)();
	}

	return false;
}
//////////////////////////////////////////////////////////////////////////

